#include "Huff.h"

//读取文件 成功返回true 失败返回false 
bool Huffman::read_from_file(char* inputDir)
{
    FILE *fr=fopen(inputDir,"r");
    if(!fr)
    {
        cout<<"Error happened when open the file"<<endl;
        return false;
    }
    char tmpC;
    float tmpF;
    fscanf(fr,"%c,%f\r",&tmpC,&tmpF);
    Node * node=new Node();
    node->feat=tmpC;
    node->prob=tmpF;
    node->left=NULL;
    node->right=NULL;

    this->all_nodes.insert(pair<float,Node*>(tmpF,node));

    while(!feof(fr))
    {
        fscanf(fr,"%c,%f\r",&tmpC,&tmpF);
        Node * node=new Node();
        node->feat=tmpC;
        node->prob=tmpF;
        node->left=NULL;
        node->right=NULL;

        this->all_nodes.insert(pair<float,Node*>(tmpF,node));
    }
    fclose(fr);
    return true;
}



bool Huffman::write_to_file(char* outDir)
{
    FILE* fw=fopen(outDir,"w");
    if(!fw)
    {
        cout<<"Error happened when open the file"<<endl;
        return false;
    }
    //TODO : 有序输出数的所有节点
    Node* tmp_node=root;
    
    trav_print(tmp_node,fw);
    fclose(fw);
    return true;

}
//执行算法，返回根节点
void Huffman::process()
{
    map<float,Node *>::iterator first;//概率最低的
    map<float,Node *>::iterator second;//概率最高的
    while(all_nodes.size()>2)
    {
        first=this->all_nodes.begin();
        second=first;
        advance(second,1);
        Node* tmp_node=new Node();
        tmp_node->feat='0';
        tmp_node->prob=first->first+second->first;
        tmp_node->left=first->second;
        tmp_node->right=second->second;
        this->all_nodes.erase(first);
        this->all_nodes.erase(second);
        this->all_nodes.insert(pair<float,Node *>(tmp_node->prob,tmp_node));
    }
    first=this->all_nodes.begin();
    second=first;
    advance(second,1);
    Node* tmp_root=new Node();
    tmp_root->feat='0';
    tmp_root->prob=first->first+second->first;
    tmp_root->left=first->second;
    tmp_root->right=second->second;
    this->all_nodes.clear();
    this->root=tmp_root;
}



void Huffman::trav_print(Node* node,FILE* fw)
{
    //Node* node=this->root;
    if((!node->left)||(!node->right))
    {
        fprintf(fw,"%c,%s\n",node->feat,this->stack.c_str());
        return;
    }
        //打印
    this->stack.push_back('0');
    this->trav_print(node->left,fw);
    this->stack.pop_back();
    this->stack.push_back('1');
    this->trav_print(node->right,fw);
    this->stack.pop_back();
    
}